﻿using System;
using System.Web;
using System.Web.SessionState;
using Machinery.Cogs.Interfaces;
using Machinery.Exceptions;

namespace Machinery.Cogs
{
    public class TimeCog : ITimeCog
    {
        private const string NowKey = "SessionTimeService_Now";


        private static HttpSessionState Session
        {
            get
            {
                try
                {
                    return HttpContext.Current.Session;
                }
                catch(NullReferenceException)
                {
                    const string errorMessage =
                        "The context of the TimeCog did not have access to Session State! " +
                        "You cannot use the TimeCog in code that does not have access to Session State.";
                    throw new CogException(errorMessage);
                }
            }   
        }

        private static DateTime? SessionNow
        {
            get {
                if (Session[NowKey] != null)
                    return (DateTime) Session[NowKey];
                return null;
            }
            set
            {
                Session[NowKey] = value;    
            }
        }

        public DateTime Now
        {
            get
            {
                return SessionNow ?? DateTime.Now;
            }
        }

        public void WarpTimeTo(DateTime warpedDateTime)
        {
            if (SessionNow == null)
                SessionNow = warpedDateTime;
            else
                throw new TimeAlreadyWarpedException
                    (
                    "Time is already warped for this session. To prevent accidental warps, " +
                    "you need to explicitly call Session.Clear() first to change the time. " 
                    );
            
        }

        
    }
}
